package com.sp.openhis.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.nacos.common.utils.IPUtil;
import com.sp.openhis.aspectj.Log;
import com.sp.openhis.aspectj.enums.BusinessType;
import com.sp.openhis.constants.Constants;
import com.sp.openhis.constants.HttpStatus;
import com.sp.openhis.controller.utils.ShiroSecurityUtils;
import com.sp.openhis.domain.LoginInfo;
import com.sp.openhis.domain.Menu;
import com.sp.openhis.dto.LoginBodyDto;
import com.sp.openhis.service.LoginInfoService;
import com.sp.openhis.service.MenuService;
import com.sp.openhis.utils.AddressUtils;
import com.sp.openhis.utils.IpUtils;
import com.sp.openhis.vo.ActiverUser;
import com.sp.openhis.vo.AjaxResult;
import com.sp.openhis.vo.MenuTreeVo;

import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.unit.DataUnit;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
public class LoginController {
    @Autowired
    private MenuService menuService;
    @Autowired
    private LoginInfoService loginInfoService;
     @PostMapping("login/doLogin")
     @Log(title = "用户登录",businessType = BusinessType.INSERT)
    public AjaxResult login(@RequestBody @Validated LoginBodyDto loginBodyDto, HttpServletRequest httpServletRequest){
         AjaxResult result = new AjaxResult();
         String username = loginBodyDto.getUsername();
         String password = loginBodyDto.getPassword();
         UsernamePasswordToken passwordToken = new UsernamePasswordToken(username,password);
         Subject subject = SecurityUtils.getSubject();
         //封装logondto对象
         LoginInfo loginInfo=creatlogininfo(httpServletRequest);
         loginInfo.setLoginAccount(loginBodyDto.getUsername());
         try {
             subject.login(passwordToken);
             Serializable webtoken = subject.getSession().getId();
             result.put(Constants.TOKEN,webtoken);
             loginInfo.setMsg("登录成功");
             loginInfo.setLoginStatus(Constants.LOGIN_SUCCESS);
             loginInfo.setUserName(ShiroSecurityUtils.getCurrentSimpleUser().getUserName());
         }catch (AuthenticationException e){
             log.error("用户名或密码不正确");
             AjaxResult.error(HttpStatus.ERROR,"用户名或密码不正确");
             loginInfo.setMsg("用户名或密码不正确");
             loginInfo.setLoginStatus(Constants.LOGIN_ERROR);
         }
         //保存登录信息到数据库
         loginInfoService.insterLonginInfo(loginInfo);
          return result;
     }

    /**
     * 创建登录对象
     * @param httpServletRequest
     * @return
     */
    private LoginInfo creatlogininfo(HttpServletRequest httpServletRequest) {
        LoginInfo loginInfo = new LoginInfo();
        UserAgent userAgent = UserAgent.parseUserAgentString(httpServletRequest.getHeader("User-Agent"));
        //获取用户ip
        String ipAddr = IpUtils.getIpAddr(httpServletRequest);
        //获取操作系统
        String name = userAgent.getOperatingSystem().getName();
        //获取浏览器类型
        String browser = userAgent.getBrowser().getName();
        //获取登陆地址
        String location = AddressUtils.getRealAddressByIP(ipAddr);

        loginInfo.setIpAddr(ipAddr);
        loginInfo.setLoginLocation(location);
        loginInfo.setBrowser(browser);
        loginInfo.setOs(name);
        loginInfo.setLoginTime(DateUtil.date());
        loginInfo.setLoginType(Constants.LOGIN_TYPE_SYSTEM);
        return loginInfo;
    }

    /**
     * 获取用户信息
     * @return
     */
    @GetMapping("/login/getInfo")
    public AjaxResult getinfo(){
         Subject subject = SecurityUtils.getSubject();
         ActiverUser activerUser = (ActiverUser) subject.getPrincipal();
         AjaxResult ajaxResult = AjaxResult.success();
         ajaxResult.put("username",activerUser.getUser().getUserName());
         ajaxResult.put("picture",activerUser.getUser().getPicture());
         ajaxResult.put("role",activerUser.getRoles());
         ajaxResult.put("permissions",activerUser.getPermissions());
         return  ajaxResult;
     }

    /**
     * 获取菜单信息
     * @return
     */
     @GetMapping("/login/getMenus")
     public AjaxResult getMenus(){
         Subject subject = SecurityUtils.getSubject();
         ActiverUser activerUser = (ActiverUser) subject.getPrincipal();
         boolean isadmin = activerUser.getUser().getUserType().equals(Constants.USER_ADMIN);
         List<Menu> menus=menuService.selectMenuTree(isadmin);
         ArrayList<MenuTreeVo> menuTreeVos = new ArrayList();
         for (Menu menu : menus) {
             menuTreeVos.add(new MenuTreeVo(menu.getMenuId().toString(),menu.getPath(),true));
         }
         return AjaxResult.success(menuTreeVos);
     }
     @PostMapping("/login/logout")
     public AjaxResult logout(){
         Subject subject = SecurityUtils.getSubject();
         subject.logout();
         return AjaxResult.success("用户退出成功");
     }
}
